﻿using System;
using YAPL.Configuration;
using YAPL.Language.Ast.Transformation;
using YAPL.Language.Compiler;
using YAPL.Language.Compiler.ILOptimization;
using YAPL.Language.SourceParser;
using YAPL.Util;

namespace YAPL.Console {
	public class ConsoleHost {
		private readonly String[] _args;

		public ConsoleHost(String[] args) {
			Require.NotNull(args, "Console arguments should not be null");
			_args = args;
		}

		public void Run() {
			System.Console.Out.WriteLine("YAPL compiler 2.1\n(C) Anton Astapov, Aleksei Statkevich, 2010.\n");
			if (_args.Length != 2) {
				System.Console.Out.WriteLine("Usage: YAPL.exe <sourcefile> <outputfile>");
				return;
			}
			try {
				var inputName = _args[0];
				var outputName = _args[1];
				var analyzer = new InputAnalyzer(new InputInfo(inputName));
				var ast = analyzer.BuildAstFromInput();
				if (Config.Instance.GetBool(Config.AST_OPTIMIZATIONS_ENABLED)) {
					var optimizer = new AstOptimizer();
					optimizer.Optimize(ast);
				}
				var outputInfo = new OutputInfo(outputName, OutputType.NetConsoleApplication);
				var compiler = new AstCompiler(outputInfo, ast);
				compiler.GenerateOutput();

				if (Config.Instance.GetBool(Config.CIL_OPTIMIZATIONS_ENABLED)) {
					var optimizer = new PeepholeOptimizer(outputName);
					optimizer.RewriteAssembly();
				}
			}
			catch (ParserException e) {
				System.Console.WriteLine(e.Message);
			}
			catch (CompilerException e) {
				System.Console.WriteLine(e.Message);
			}
		}
	}
}